package com.example.d6_lambda;

import com.example.d5_arrays.Student;

import java.util.Arrays;
import java.util.Comparator;

/**
 * 目标：使用Lambda简化函数式接口
 */
public class LambdaTest2 {
    public static void main(String[] args) {
        double[] prices = {99.8, 128, 100};
        // 使用Arrays.setAll方法来统一修改prices数组中的元素值
        // 1.把所有元素*0.8: 先用匿名内部类写法
//        Arrays.setAll(prices, new IntToDoubleFunction() {
//            /**
//             * 将数组中的每个元素乘以0.8
//             * @param value 索引值,用于访问数组中的对应元素
//             * @return 修改后的元素值
//             */
//            @Override
//            public double applyAsDouble(int value) {
//                // value = 0  1  2
//                return prices[value] * 0.8;
//            }
//        });

        // 2.把所有元素*0.8: 改用Lambda表达式写法 和上面的效果是一致的
        /*
        Lambda表达式的省略写法
        1.参数类型可以省略不写
        2.如果只有一个参数,参数类型可以省略,同时小括号()可以省略不写
        3.如果Lambda表达式中的方法体只有一行代码,大括号{}可以省略不写 同时要省略分号 此时如果这行代码是return语句,那么也必须去掉return不写
        4.
         */
        // 原始的lambda表达式
//        Arrays.setAll(prices, (int value) -> {
//            // value = 0  1  2
//            return prices[value] * 0.8;
//        });

        // 1.参数类型可以省略不写
//        Arrays.setAll(prices, (value) -> {
//            // value = 0  1  2
//            return prices[value] * 0.8;
//        });

        // 2.如果只有一个参数,参数类型可以省略,同时小括号()可以省略不写
//        Arrays.setAll(prices, value -> {
//            // value = 0  1  2
//            return prices[value] * 0.8;
//        });

        // 3.如果Lambda表达式中的方法体只有一行代码,大括号{}可以省略不写 同时要省略分号 此时如果这行代码是return语句,那么也必须去掉return不写
        Arrays.setAll(prices, value -> prices[value] * 0.8);


        System.out.println(Arrays.toString(prices));
        System.out.println("-----------------------------------------------");


        Student[] students = new Student[4];
        students[0] = new Student("蜘蛛精", 169.5, 23);
        students[1] = new Student("紫霞", 163.8, 26);
        students[2] = new Student("紫霞", 163.8, 26);
        students[3] = new Student("至尊宝", 167.5, 24);
        // 3.对数组中的元素按照年龄升序排列: 先用匿名内部类写法
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 这里new 了一个 Comparator接口的匿名内部类 用于比较自定义的对象
                // 由于在Student类中Height属性是double类型,但是Comparator接口的compare方法返回值是int类型
                // 所以需要使用Double.compare()方法 因为该方法的返回值是int
                return Double.compare(o1.getHeight(), o2.getHeight()); // 升序
            }
        });
        // 4.对数组中的元素按照年龄升序排列: 改用Lambda写法
//        Arrays.sort(students, (Student o1, Student o2) -> {
//            return Double.compare(o1.getHeight(), o2.getHeight()); // 升序
//        });

        // 1.参数类型可以省略不写   注意这里就不能省略小括号了 因为参数是两个了
        Arrays.sort(students, (o1, o2) -> {
            return Double.compare(o1.getHeight(), o2.getHeight()); // 升序
        });

        // 3.如果Lambda表达式中的方法体只有一行代码,大括号{}可以省略不写 同时要省略分号 此时如果这行代码是return语句,那么也必须去掉return不写
        Arrays.sort(students, (Student o1, Student o2) -> Double.compare(o1.getHeight(), o2.getHeight()));

        Arrays.sort(students, ( o1,  o2) -> Double.compare(o1.getHeight(), o2.getHeight()));

        Arrays.sort(students, Comparator.comparingDouble(Student::getHeight));

        System.out.println(Arrays.toString(students));
    }
}
